home *** CD-ROM | disk | FTP | other *** search
- Subject: v06i111: Xlisp version 1.6 (xlisp1.6), Part05/06
- Newsgroups: mod.sources
- Approved: rs@mirror.UUCP
-
- Submitted by: seismo!utah-cs!b-davis (Brad Davis)
- Mod.sources: Volume 6, Issue 111
- Archive-name: xlisp1.6/Part05
-
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # art.lsp
- # example.lsp
- # fact.lsp
- # fib.lsp
- # hanoi.lsp
- # hdwr.lsp
- # ifthen.lsp
- # init.lsp
- # object.lsp
- # pcturtle.lsp
- # pp.lsp
- # prolog.lsp
- # pt.lsp
- # queens.lsp
- # queens2.lsp
- # simplepp.lsp
- # trace.lsp
- # This archive created: Mon Jul 14 10:16:59 1986
- export PATH; PATH=/bin:$PATH
- if test -f 'art.lsp'
- then
- echo shar: will not over-write existing file "'art.lsp'"
- else
- cat << \SHAR_EOF > 'art.lsp'
- ; This is an example using the object-oriented programming support in
- ; XLISP. The example involves defining a class of objects representing
- ; dictionaries. Each instance of this class will be a dictionary in
- ; which names and values can be stored. There will also be a facility
- ; for finding the values associated with names after they have been
- ; stored.
-
- ; Create the 'Dictionary' class and establish its instance variable list.
- ; The variable 'entries' will point to an association list representing the
- ; entries in the dictionary instance.
-
- (setq Dictionary (Class :new '(entries)))
-
- ; Setup the method for the ':isnew' initialization message.
- ; This message will be send whenever a new instance of the 'Dictionary'
- ; class is created. Its purpose is to allow the new instance to be
- ; initialized before any other messages are sent to it. It sets the value
- ; of 'entries' to nil to indicate that the dictionary is empty.
-
- (Dictionary :answer :isnew '()
- '((setq entries nil)
- self))
-
- ; Define the message ':add' to make a new entry in the dictionary. This
- ; message takes two arguments. The argument 'name' specifies the name
- ; of the new entry; the argument 'value' specifies the value to be
- ; associated with that name.
-
- (Dictionary :answer :add '(name value)
- '((setq entries
- (cons (cons name value) entries))
- value))
-
- ; Create an instance of the 'Dictionary' class. This instance is an empty
- ; dictionary to which words may be added.
-
- (setq d (Dictionary :new))
-
- ; Add some entries to the new dictionary.
-
- (d :add 'mozart 'composer)
- (d :add 'winston 'computer-scientist)
-
- ; Define a message to find entries in a dictionary. This message takes
- ; one argument 'name' which specifies the name of the entry for which to
- ; search. It returns the value associated with the entry if one is
- ; present in the dictionary. Otherwise, it returns nil.
-
- (Dictionary :answer :find '(name &aux entry)
- '((cond ((setq entry (assoc name entries))
- (cdr entry))
- (t
- nil))))
-
- ; Try to find some entries in the dictionary we created.
-
- (d :find 'mozart)
- (d :find 'winston)
- (d :find 'bozo)
-
- ; The names 'mozart' and 'winston' are found in the dictionary so their
- ; values 'composer' and 'computer-scientist' are returned. The name 'bozo'
- ; is not found so nil is returned in this case.
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'example.lsp'
- then
- echo shar: will not over-write existing file "'example.lsp'"
- else
- cat << \SHAR_EOF > 'example.lsp'
- ; Make the class ship and its instance variables be known
-
- (setq ship (Class :new '(x y xv yv m name captain registry)))
-
-
- (ship :answer :getx '() '( x )) ; just evaluate x
- (ship :answer :getxv '() '( xv )) ; note that the method is a
- (ship :answer :gety '() '( y )) ; list of forms, the value
- (ship :answer :getyv '() '( yv )) ; of the last one being the
- (ship :answer :getm '() '( m )) ; value of the method
- (ship :answer :getname '() '( name ))
- (ship :answer :getcaptain '() '( captain ))
- (ship :answer :getregistry '() '( registry ))
-
- ; formal
- ; param
- ; of
- ; method
- (ship :answer :setx '(to) '( (setq x to) ) )
- (ship :answer :setxv '(to) '( (setq xv to) ) )
- (ship :answer :sety '(to) '( (setq y to) ) )
- (ship :answer :setyv '(to) '( (setq yv to) ) )
- (ship :answer :setm '(to) '( (setq m to) ) )
- (ship :answer :setname '(to) '( (setq name to) ) )
- (ship :answer :setcaptain '(to) '( (setq captain to) ) )
- (ship :answer :setregistry '(to) '( (setq registry to) ) )
-
- (ship :answer :sail '(time)
- ; the METHOD for sailing
- '( (princ (list "sailing for " time " hours\n"))
- ; note that this form is expressed in terms of objects: "self"
- ; is bound to the object being talked to during the execution
- ; of its message. It can ask itself to do things.
- (self :setx (+ (self :getx)
- (* (self :getxv) time)))
- ; This form performs a parallel action to the above, but more
- ; efficiently, and in this instance, more clearly
- (setq y (+ y (* yv time)))
- ; Cute message for return value. Tee Hee.
- "Sailing, sailing, over the bountiful chow mein..."))
-
- ; <OBJECT: #12345667> is not terribly instructive. How about a more
- ; informative print routine?
-
- (ship :answer :print '() '((princ (list
- "SHIP NAME: " (self :getname) "\n"
- "REGISTRY: " (self :getregistry) "\n"
- "CAPTAIN IS: " (self :getcaptain) "\n"
- "MASS IS: " (self :getm) " TONNES\n"
- "CURRENT POSITION IS: "
- (self :getx) " X BY "
- (self :gety) " Y\n"
- "SPEED IS: "
- (self :getxv) " XV BY "
- (self :getyv) " YV\n") ) ))
-
- ; a function to make life easier
-
- (defun newship (mass name registry captain &aux new)
- (setq new (ship :new))
- (new :setx 0)
- (new :sety 0)
- (new :setxv 0)
- (new :setyv 0)
- (new :setm mass)
- (new :setname name)
- (new :setcaptain captain)
- (new :setregistry registry)
- (new :print)
- new)
-
- ; and an example object.
-
- (setq Bounty (newship 50 'Bounty 'England 'Bligh))
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'fact.lsp'
- then
- echo shar: will not over-write existing file "'fact.lsp'"
- else
- cat << \SHAR_EOF > 'fact.lsp'
- (defun factorial (n)
- (cond ((= n 1) 1)
- (t (* n (factorial (- n 1))))))
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'fib.lsp'
- then
- echo shar: will not over-write existing file "'fib.lsp'"
- else
- cat << \SHAR_EOF > 'fib.lsp'
- (defun fib (x)
- (if (< x 2)
- x
- (+ (fib (1- x)) (fib (- x 2)))))
-
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'hanoi.lsp'
- then
- echo shar: will not over-write existing file "'hanoi.lsp'"
- else
- cat << \SHAR_EOF > 'hanoi.lsp'
- ; Good ol towers of hanoi
- ;
- ; Usage:
- ; (hanoi <n>)
- ; <n> - an integer the number of discs
-
- (defun hanoi(n)
- ( transfer 'A 'B 'C n ))
-
- (defun print-move ( from to )
- (princ "Move Disk From ")
- (princ from)
- (princ " To ")
- (princ to)
- (princ "\n"))
-
-
- (defun transfer ( from to via n )
- (cond ((equal n 1) (print-move from to ))
- (t (transfer from via to (- n 1))
- (print-move from to)
- (transfer via to from (- n 1)))))
-
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'hdwr.lsp'
- then
- echo shar: will not over-write existing file "'hdwr.lsp'"
- else
- cat << \SHAR_EOF > 'hdwr.lsp'
- ; -*-Lisp-*-
- ;
- ; Jwahar R. Bammi
- ; A simple description of hardware objects using xlisp
- ; Mix and match instances of the objects to create your
- ; organization.
- ; Needs:
- ; - busses and connection and the Design
- ; Class that will have the connections as instance vars.
- ; - Print method for each object, that will display
- ; the instance variables in an human readable form.
- ; Some day I will complete it.
- ;
- ;
- ;
- ; utility functions
-
-
- ; function to calculate 2^n
-
- (defun pow2 (n)
- (pow2x n 1))
-
- (defun pow2x (n sum)
- (cond((equal n 0) sum)
- (t (pow2x (- n 1) (* sum 2)))))
-
-
- ; hardware objects
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;The class areg
-
- (setq areg (Class :new '(value nbits max_val min_val)))
-
- ; methods
-
- ; initialization method
- ; when a new instance is called for the user supplies
- ; the parameter nbits, from which the max_val & min_val are derived
-
- (areg :answer :isnew '(n)
- '((self :init n)
- self))
-
- (areg :answer :init '(n)
- '((setq value ())
- (setq nbits n)
- (setq max_val (- (pow2 (- n 1)) 1))
- (setq min_val (- (- 0 max_val) 1))))
-
- ; load areg
-
- (areg :answer :load '(val)
- '((cond ((> val max_val) (princ (list "The max value a "nbits" bit register can hold is "max_val"\n")))
- ((< val min_val) (princ (list "The min value a "nbits" bit register can hold is "min_val"\n")))
- (t (setq value val)))))
-
- ; see areg
-
- (areg :answer :see '()
- '((cond ((null value) (princ "Register does not contain a value\n"))
- (t value))))
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ; The class creg ( a register that can be cleared and incremented)
- ; subclass of a reg
-
- (setq creg (Class :new '() '() areg))
-
- ; it inherites all the instance vars & methods of a reg
- ; in addition to them it has the following methods
-
- (creg :answer :isnew '(n)
- '((self :init n)
- self))
-
- (creg :answer :init '(n)
- '((setq value ())
- (setq nbits n)
- (setq max_val (- (pow2 n) 1))
- (setq min_val 0)))
-
- (creg :answer :clr '()
- '((setq value 0)))
-
- (creg :answer :inc '()
- '((cond ((null value) (princ "Register does not contain a value\n"))
- (t (setq value (rem (+ value 1) (+ max_val 1)))))))
-
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; Register bank
- ; contains n areg's n_bits each
-
- (setq reg_bank (Class :new '(regs n_regs curr_reg)))
-
- ;methods
-
- (reg_bank :answer :isnew '(n n_bits)
- '((self :init n n_bits)
- self))
-
- (reg_bank :answer :init '(n n_bits)
- '((setq regs ())
- (setq n_regs (- n 1))
- (self :initx n n_bits)))
-
- (reg_bank :answer :initx '(n n_bits)
- '((cond ((equal n 0) t)
- (t (list (setq regs (cons (areg :new n_bits) regs))
- (self :initx (setq n (- n 1)) n_bits))))))
-
- (reg_bank :answer :load '(reg val)
- '((cond((> reg n_regs) (princ (list "Only "(+ 1 n_regs)" registers instantiated\n")))
- (t (setq curr_reg (nth (+ reg 1) regs))
- (curr_reg :load val)))))
-
- (reg_bank :answer :see '(reg)
- '((cond((> reg n_regs) (princ (list "Only "(+ 1 n_regs)" registers instantiated\n")))
- (t (setq curr_reg (nth (+ reg 1) regs))
- (curr_reg :see)))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; The Class alu
-
- ;alu - an n bit alu
-
- (setq alu (Class :new '(n_bits maxs_val mins_val maxu_val minu_val nf zf vf cf)))
-
- ; methods
-
- (alu :answer :isnew '(n)
- '((self :init n)
- self))
-
- (alu :answer :init '(n)
- '((setq n_bits n)
- (setq maxu_val (- (pow2 n) 1))
- (setq maxs_val (- (pow2 (- n 1)) 1))
- (setq mins_val (- (- 0 maxs_val) 1))
- (setq minu_val 0)
- (setq nf 0)
- (setq zf 0)
- (setq vf 0)
- (setq cf 0)))
-
- (alu :answer :check_arith '(a b)
- '((cond ((and (self :arith_range a) (self :arith_range b)) t)
- (t ()))))
-
- (alu :answer :check_logic '(a b)
- '((cond ((and (self :logic_range a) (self :logic_range b)) t)
- (t ()))))
-
- (alu :answer :arith_range '(a)
- '((cond ((< a mins_val) (princ (list "Operand out of Range "a"\n")))
- ((> a maxs_val) (princ (list "Operand out of range "a"\n")))
- (t t))))
-
- (alu :answer :logic_range '(a)
- '((cond ((< (abs a) minu_val) (princ (list "Operand out of Range "a"\n")))
- (t t))))
-
- (alu :answer :set_flags '(a b r)
- '((if (equal 0 r) ((setq zf 1)))
- (if (< r 0) ((setq nf 1)))
- (if (or (and (and (< a 0) (< 0 b)) (>= r 0))
- (and (and (>= a 0) (>= b 0)) (< r 0))) ((setq vf 1)))
- (if (or (or (and (< a 0) (< b 0)) (and (< a 0) (>= r 0)))
- (and (>= r 0) (< b 0))) ((setq cf 1)))))
-
- (alu :answer :+ '(a b &aux result)
- '((cond ((null (self :check_arith a b)) ())
- (t (self :clear_flags)
- (setq result (+ a b))
- (if (> result maxs_val) ((setq result (+ (- (rem result maxs_val) 1) mins_val))))
- (if (< result mins_val) ((setq result (+ (rem result mins_val) (+ maxs_val 1)))))
- (self :set_flags a b result)
- result))))
-
- (alu :answer :& '(a b &aux result)
- '((cond ((null (self :check_logic a b)) ())
- (t (self :clear_flags)
- (setq result (bit-and a b))
- (self :set_flags a b result)
- result))))
-
- (alu :answer :| '(a b &aux result)
- '((cond ((null (self :check_logic a b)) ())
- (t (self :clear_flags)
- (setq result (bit-ior a b))
- (self :set_flags a b result)
- result))))
-
- (alu :answer :~ '(a &aux result)
- '((cond ((null (self :check_logic a 0)) ())
- (t (self :clear_flags)
- (setq result (bit-not a))
- (self :set_flags a 0 result)
- result))))
-
- (alu :answer :- '(a b)
- '((self '+ a (- 0 b))))
-
- (alu :answer :passa '(a)
- '(a))
-
- (alu :answer :zero '()
- '(0))
-
- (alu :answer :com '(a)
- '((self :- 0 a)))
-
- (alu :answer :status '()
- '((princ (list "NF "nf"\n"))
- (princ (list "ZF "zf"\n"))
- (princ (list "CF "cf"\n"))
- (princ (list "VF "vf"\n"))))
-
- (alu :answer :clear_flags '()
- '((setq nf 0)
- (setq zf 0)
- (setq cf 0)
- (setq vf 0)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; The class Memory
- ;
-
- (setq memory (Class :new '(nabits ndbits maxu_val maxs_val mins_val max_addr undef memry)))
-
- ; methods
-
- (memory :answer :isnew '(addr_bits data_bits)
- '((self :init addr_bits data_bits)
- self))
-
- (memory :answer :init '(addr_bits data_bits)
- '((setq nabits addr_bits)
- (setq ndbits data_bits)
- (setq maxu_val (- (pow2 data_bits) 1))
- (setq max_addr (- (pow2 addr_bits) 1))
- (setq maxs_val (- (pow2 (- data_bits 1)) 1))
- (setq mins_val (- 0 (pow2 (- data_bits 1))))
- (setq undef (+ maxu_val 1))
- (setq memry (array :new max_addr undef))))
-
-
- (memory :answer :load '(loc val)
- '((cond ((> (abs loc) max_addr) (princ (list "Address "loc" out of range\n")))
- ((< val 0) (princ (list "Cant store "val" in "ndbits" bits\n")))
- ((> val maxu_val) (princ (list "Cant store "val" in "ndbits" bits\n")))
- (t (memry :load loc val)))))
-
- (memory :answer :write '(loc val)
- '((cond ((> (abs loc) max_addr) (princ (list "Address "loc" out of range\n")))
- ((> val maxs_val) (princ (list "Cant store "val" in "ndbits" bits\n")))
- ((< val mins_val) (princ (list "Cant store "val" in "ndbits" bits\n")))
- (t (memry :load loc val)))))
-
-
- (memory :answer :read '(loc &aux val)
- '((cond ((> (abs loc) max_addr) (princ (list "Address "loc" out of range\n")))
- (t (setq val (memry :see loc))
- (cond ((equal undef val) (princ (list "Address "loc" read before write\n")))
- (t val))))))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; The class array
-
- (setq array (Class :new '(arry)))
-
- ; methods
-
- (array :answer :isnew '(n val)
- '((self :init n val)
- self))
-
- (array :answer :init '(n val)
- '((cond ((< n 0) t)
- (t (setq arry (cons val arry))
- (self :init (- n 1) val)))))
-
- (array :answer :see '(n)
- '((nth (+ n 1) arry)))
-
-
- (array :answer :load '(n val &aux left right temp)
- '((setq left (self :left_part n arry temp))
- (setq right (self :right_part n arry))
- (setq arry (append left (list val)))
- (setq arry (append arry right))
- val))
-
- (array :answer :left_part '(n ary left)
- '((cond ((equal n 0) (reverse left))
- (t (setq left (cons (car ary) left))
- (self :left_part (- n 1) (cdr ary) left)))))
-
- (array :answer :right_part '(n ary &aux right)
- '((cond ((equal n 0) (cdr ary))
- (t (self :right_part (- n 1) (cdr ary))))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'ifthen.lsp'
- then
- echo shar: will not over-write existing file "'ifthen.lsp'"
- else
- cat << \SHAR_EOF > 'ifthen.lsp'
- ; -*-Lisp-*-
- ;
- ; If then rules - mini expert from Ch. 18 of Winston and Horn
- ; Written using recursion without progs
- ; Added function 'how' to explain deductions
- ;
- ; Use:
- ; After loading type (deduce). It will make all the deductions
- ; given the list fact. If you want to know how it deduced something
- ; type (how '(a deduction)) for example (how '(animal is tiger))
- ; and so on.
-
-
-
- ; rules data base
-
- (setq rules
- '((rule identify1
- (if (animal has hair))
- (then (animal is mammal)))
- (rule identify2
- (if (animal gives milk))
- (then (animal is mammal)))
- (rule identify3
- (if (animal has feathers))
- (then (animal is bird)))
- (rule identify4
- (if (animal flies)
- (animal lays eggs))
- (then (animal is bird)))
- (rule identify5
- (if (animal eats meat))
- (then (animal is carnivore)))
- (rule identify6
- (if (animal has pointed teeth)
- (animal has claws)
- (animal has forward eyes))
- (then (animal is carnivore)))
- (rule identify7
- (if (animal is mammal)
- (animal has hoofs))
- (then (animal is ungulate)))
- (rule identify8
- (if (animal is mammal)
- (animal chews cud))
- (then (animal is ungulate)
- (even toed)))
- (rule identify9
- (if (animal is mammal)
- (animal is carnivore)
- (animal has tawny color)
- (animal has dark spots))
- (then (animal is cheetah)))
- (rule identify10
- (if (animal is mammal)
- (animal is carnivore)
- (animal has tawny color)
- (animal has black stripes))
- (then (animal is tiger)))
- (rule identify11
- (if (animal is ungulate)
- (animal has long neck)
- (animal has long legs)
- (animal has dark spots))
- (then (animal is giraffe)))
- (rule identify12
- (if (animal is ungulate)
- (animal has black stripes))
- (then (animal is zebra)))
- (rule identify13
- (if (animal is bird)
- (animal does not fly)
- (animal has long neck)
- (animal has long legs)
- (animal is black and white))
- (then (animal is ostrich)))
- (rule identify14
- (if (animal is bird)
- (animal does not fly)
- (animal swims)
- (animal is black and white))
- (then (animal is penguin)))
- (rule identify15
- (if (animal is bird)
- (animal flys well))
- (then (animal is albatross)))))
- ; utility functions
- (defun squash(s)
- (cond ((null s) ())
- ((atom s) (list s))
- (t (append (squash (car s))
- (squash (cdr s))))))
-
- (defun p(s)
- (princ (squash s)))
-
- ; functions
-
- ; function to see if an item is a member of a list
-
- (defun member(item list)
- (cond((null list) ()) ; return nil on end of list
- ((equal item (car list)) list) ; found
- (t (member item (cdr list))))) ; otherwise try rest of list
-
- ; put a new fact into the facts data base if it is not already there
-
- (defun remember(newfact)
- (cond((member newfact facts) ()) ; if present do nothing
- (t ( setq facts (cons newfact facts)) newfact)))
-
- ; is a fact there in the facts data base
-
- (defun recall(afact)
- (cond ((member afact facts) afact) ; it is here
- (t ()))) ; no it is'nt
-
- ; given a rule check if all the if parts are confirmed by the facts data base
-
- (defun testif(iflist)
- (cond((null iflist) t) ; all satisfied
- ((recall (car iflist)) (testif (cdr iflist))) ; keep searching
- ; if one is ok
- (t ()))) ; not in facts DB
-
- ; add the then parts of the rules which can be added to the facts DB
- ; return the ones that are added
-
- (defun usethen(thenlist addlist)
- (cond ((null thenlist) addlist) ; all exhausted
- ((remember (car thenlist))
- (usethen (cdr thenlist) (cons (car thenlist) addlist)))
- (t (usethen (cdr thenlist) addlist))))
-
- ; try a rule
- ; return t only if all the if parts are satisfied by the facts data base
- ; and at lest one then ( conclusion ) is added to the facts data base
-
- (defun tryrule(rule &aux ifrules thenlist addlist)
- (setq ifrules (cdr(car(cdr(cdr rule)))))
- (setq thenlist (cdr(car(cdr(cdr(cdr rule))))))
- (setq addlist '())
- (cond (( testif ifrules)
- (cond ((setq addlist (usethen thenlist addlist))
- (p (list "Rule " (car(cdr rule)) "\n\tDeduced " addlist "\n\n"))
- (setq ruleused (cons rule ruleused))
- t)
- (t ())))
- (t ())))
-
- ; step through one iteration if the forward search
- ; looking for rules that can be deduced from the present fact data base
-
- (defun stepforward( rulelist)
- (cond((null rulelist) ()) ; all done
- ((tryrule (car rulelist)) t)
- ( t (stepforward(cdr rulelist)))))
-
- ; stepforward until you cannot go any further
-
- (defun deduce()
- (cond((stepforward rules) (deduce))
- (t t)))
-
- ; function to answer if a fact was used to come to a certain conclusion
- ; uses the ruleused list cons'ed by tryrule to answer
-
- (defun usedp(rule)
- (cond ((member rule ruleused) t) ; it has been used
- (t () ))) ; no it hasnt
-
- ; function to answer how a fact was deduced
-
- (defun how(fact)
- (how2 fact ruleused nil))
-
- (defun how2(fact rulist found)
- (cond ((null rulist) ; if the rule list exhausted
- (cond (found t) ; already answered the question return t
- ((recall fact) (p (list fact " was a given fact\n")) t) ;known fact
- (t (p (list fact " -- not a fact!\n")) ())))
-
- ((member fact (thenpart (car rulist))) ; if rulist not empty
- (setq found t) ; and fact belongs to the then part of a rule
- (p (list fact " was deduced because the following were true\n"))
- (printifs (car rulist))
- (how2 fact (cdr rulist) found))
- (t (how2 fact (cdr rulist) found))))
-
- ; function to return the then part of a rule
-
- (defun thenpart(rule)
- (cdr(car(cdr(cdr(cdr rule))))))
-
- ; function to print the if part of a given rule
-
- (defun printifs(rule)
- (pifs (cdr(car(cdr(cdr rule))))))
-
- (defun pifs(l)
- (cond ((null l) ())
- (t (p (list "\t" (car l) "\n"))
- (pifs (cdr l)))))
-
-
- ; initial facts data base
- ; Uncomment one or make up your own
- ; Then run 'deduce' to find deductions
- ; Run 'how' to find out how it came to a certain deduction
-
- ;(setq facts
- ; '((animal has dark spots)
- ; (animal has tawny color)
- ; (animal eats meat)
- ; (animal has hair)))
-
- (setq facts
- '((animal has hair)
- (animal has pointed teeth)
- (animal has black stripes)
- (animal has claws)
- (animal has forward eyes)
- (animal has tawny color)))
-
-
- (setq rl1
- '(rule identify14
- (if (animal is bird)
- (animal does not fly)
- (animal swims)
- (animal is black and white))
- (then (animal is penguin))))
-
- (setq rl2
- '(rule identify10
- (if (animal is mammal)
- (animal is carnivore)
- (animal has tawny color)
- (animal has black stripes))
- (then (animal is tiger))))
-
- ; Initialization
- (expand 10)
- (setq ruleused nil)
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'init.lsp'
- then
- echo shar: will not over-write existing file "'init.lsp'"
- else
- cat << \SHAR_EOF > 'init.lsp'
- ; initialization file for XLISP 1.6
-
- ; get some more memory
- (expand 1)
-
- ; some fake definitions for Common Lisp pseudo compatiblity
- (setq first car)
- (setq second cadr)
- (setq rest cdr)
-
- ; (when test code...) - execute code when test is true
- (defmacro when (test &rest code)
- `(cond (,test ,@code)))
-
- ; (unless test code...) - execute code unless test is true
- (defmacro unless (test &rest code)
- `(cond ((not ,test) ,@code)))
-
- ; (makunbound sym) - make a symbol be unbound
- (defun makunbound (sym) (setq sym '*unbound*) sym)
-
- ; (objectp expr) - object predicate
- (defun objectp (x) (eq (type-of x) :OBJECT))
-
- ; (filep expr) - file predicate
- (defun filep (x) (eq (type-of x) :FILE))
-
- ; (unintern sym) - remove a symbol from the oblist
- (defun unintern (sym) (cond ((member sym *oblist*)
- (setq *oblist* (delete sym *oblist*))
- t)
- (t nil)))
-
- ; (mapcan fun list [ list ]...)
- (defmacro mapcan (&rest args) `(apply #'nconc (mapcar ,@args)))
-
- ; (mapcon fun list [ list ]...)
- (defmacro mapcon (&rest args) `(apply #'nconc (maplist ,@args)))
-
- ; (set-macro-character ch fun [ tflag ])
- (defun set-macro-character (ch fun &optional tflag)
- (setf (aref *readtable* ch) (cons (if tflag :tmacro :nmacro) fun))
- t)
-
- ; (get-macro-character ch)
- (defun get-macro-character (ch)
- (if (consp (aref *readtable* ch))
- (cdr (aref *readtable* ch))
- nil))
-
- ; (save fun) - save a function definition to a file
- (defmacro save (fun)
- `(let* ((fname (strcat (symbol-name ',fun) ".lsp"))
- (fval (car ,fun))
- (fp (openo fname)))
- (cond (fp (print (cons (if (eq (car fval) 'lambda)
- 'defun
- 'defmacro)
- (cons ',fun (cdr fval))) fp)
- (close fp)
- fname)
- (t nil))))
-
- ; (debug) - enable debug breaks
- (defun debug ()
- (setq *breakenable* t))
-
- ; (nodebug) - disable debug breaks
- (defun nodebug ()
- (setq *breakenable* nil))
-
- ; initialize to enable breaks but no trace back
- (setq *breakenable* t)
- (setq *tracenable* nil)
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'object.lsp'
- then
- echo shar: will not over-write existing file "'object.lsp'"
- else
- cat << \SHAR_EOF > 'object.lsp'
- ; This is an example using the object-oriented programming support in
- ; XLISP. The example involves defining a class of objects representing
- ; dictionaries. Each instance of this class will be a dictionary in
- ; which names and values can be stored. There will also be a facility
- ; for finding the values associated with names after they have been
- ; stored.
-
- ; Create the 'Dictionary' class.
-
- (setq Dictionary (Class 'new))
-
- ; Establish the instance variables for the new class.
- ; The variable 'entries' will point to an association list representing the
- ; entries in the dictionary instance.
-
- (Dictionary 'ivars '(entries))
-
- ; Setup the method for the 'isnew' initialization message.
- ; This message will be send whenever a new instance of the 'Dictionary'
- ; class is created. Its purpose is to allow the new instance to be
- ; initialized before any other messages are sent to it. It sets the value
- ; of 'entries' to nil to indicate that the dictionary is empty.
-
- (Dictionary 'answer 'isnew '()
- '((setq entries nil)
- self))
-
- ; Define the message 'add' to make a new entry in the dictionary. This
- ; message takes two arguments. The argument 'name' specifies the name
- ; of the new entry; the argument 'value' specifies the value to be
- ; associated with that name.
-
- (Dictionary 'answer 'add '(name value)
- '((setq entries
- (cons (cons name value) entries))
- value))
-
- ; Create an instance of the 'Dictionary' class. This instance is an empty
- ; dictionary to which words may be added.
-
- (setq d (Dictionary 'new))
-
- ; Add some entries to the new dictionary.
-
- (d 'add 'mozart 'composer)
- (d 'add 'winston 'computer-scientist)
-
- ; Define a message to find entries in a dictionary. This message takes
- ; one argument 'name' which specifies the name of the entry for which to
- ; search. It returns the value associated with the entry if one is
- ; present in the dictionary. Otherwise, it returns nil.
-
- (Dictionary 'answer 'find '(name &aux entry)
- '((cond ((setq entry (assoc name entries))
- (cdr entry))
- (t
- nil))))
-
- ; Try to find some entries in the dictionary we created.
-
- (d 'find 'mozart)
- (d 'find 'winston)
- (d 'find 'bozo)
-
- ; The names 'mozart' and 'winston' are found in the dictionary so their
- ; values 'composer' and 'computer-scientist' are returned. The name 'bozo'
- ; is not found so nil is returned in this case.
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'pcturtle.lsp'
- then
- echo shar: will not over-write existing file "'pcturtle.lsp'"
- else
- cat << \SHAR_EOF > 'pcturtle.lsp'
- ; This is a sample XLISP program
- ; It implements a simple form of programmable turtle for IBM-PC compatible
- ; machines.
-
- ; To run it:
-
- ; A>xlisp pt
-
- ; This should cause the screen to be cleared and two turtles to appear.
- ; They should each execute their simple programs and then the prompt
- ; should return. Look at the code to see how all of this works.
-
- ; Get some more memory
- (expand 1)
-
- ; Move the cursor to the currently set bottom position and clear the line
- ; under it
- (defun bottom ()
- (set-cursor by bx)
- (clear-eos))
-
- ; Clear the screen and go to the bottom
- (defun cb ()
- (clear)
- (bottom))
-
-
- ; ::::::::::::
- ; :: Turtle ::
- ; ::::::::::::
-
- ; Define "Turtle" class
- (setq Turtle (Class :new '(xpos ypos char)))
-
- ; Answer ":isnew" by initing a position and char and displaying.
- (Turtle :answer :isnew '() '(
- (setq xpos (setq newx (+ newx 1)))
- (setq ypos 12)
- (setq char "*")
- (self :display)
- self))
-
- ; Message ":display" prints its char at its current position
- (Turtle :answer :display '() '(
- (set-cursor ypos xpos)
- (princ char)
- (bottom)
- self))
-
- ; Message ":char" sets char to its arg and displays it
- (Turtle :answer :char '(c) '(
- (setq char c)
- (self :display)))
-
- ; Message ":goto" goes to a new place after clearing old one
- (Turtle :answer :goto '(x y) '(
- (set-cursor ypos xpos) (princ " ")
- (setq xpos x)
- (setq ypos y)
- (self :display)))
-
- ; Message ":up" moves up if not at top
- (Turtle :answer :up '() '(
- (if (> ypos 1)
- (self :goto xpos (- ypos 1))
- (bottom))))
-
- ; Message ":down" moves down if not at bottom
- (Turtle :answer :down '() '(
- (if (< ypos by)
- (self :goto xpos (+ ypos 1))
- (bottom))))
-
- ; Message ":right" moves right if not at right
- (Turtle :answer :right '() '(
- (if (< xpos 80)
- (self :goto (+ xpos 1) ypos)
- (bottom))))
-
- ; Message ":left" moves left if not at left
- (Turtle :answer :left '() '(
- (if (> xpos 1)
- (self :goto (- xpos 1) ypos)
- (bottom))))
-
-
- ; :::::::::::::
- ; :: PTurtle ::
- ; :::::::::::::
-
- ; Define "DPurtle" programable turtle class
- (setq PTurtle (Class :new '(prog pc) '() Turtle))
-
- ; Message ":program" stores a program
- (PTurtle :answer :program '(p) '(
- (setq prog p)
- (setq pc prog)
- self))
-
- ; Message ":step" executes a single program step
- (PTurtle :answer :step '() '(
- (if (null pc)
- (setq pc prog))
- (if pc
- (progn (self (car pc))
- (setq pc (cdr pc))))
- self))
-
- ; Message ":step#" steps each turtle program n times
- (PTurtle :answer :step# '(n) '(
- (dotimes (x n) (self :step))
- self))
-
-
- ; ::::::::::::::
- ; :: PTurtles ::
- ; ::::::::::::::
-
- ; Define "PTurtles" class
- (setq PTurtles (Class :new '(turtles)))
-
- ; Message ":make" makes a programable turtle and adds it to the collection
- (PTurtles :answer :make '(x y &aux newturtle) '(
- (setq newturtle (PTurtle :new))
- (newturtle :goto x y)
- (setq turtles (cons newturtle turtles))
- newturtle))
-
- ; Message ":step" steps each turtle program once
- (PTurtles :answer :step '() '(
- (mapcar '(lambda (turtle) (turtle :step)) turtles)
- self))
-
- ; Message ":step#" steps each turtle program n times
- (PTurtles :answer :step# '(n) '(
- (dotimes (x n) (self :step))
- self))
-
-
- ; Initialize things and start up
- (setq bx 1)
- (setq by 21)
- (setq newx 1)
-
- ; Create some programmable turtles
- (cb)
- (setq turtles (PTurtles :new))
- (setq t1 (turtles :make 40 10))
- (setq t2 (turtles :make 41 10))
- (t1 :program '(:left :right :up :down))
- (t2 :program '(:right :left :down :up))
-
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'pp.lsp'
- then
- echo shar: will not over-write existing file "'pp.lsp'"
- else
- cat << \SHAR_EOF > 'pp.lsp'
- ;+
- ; PP 1.0 : (C) Copyright 1985 by Gregory Frascadore
- ;
- ; This software may be copied, modified, and distributed to others as long
- ; as it is not sold for profit, and as long as this copyright notice is
- ; retained intact. For further information contact the author at:
- ; frascado%umn-cs.CSNET (on CSNET)
- ; 75106,662 (on CompuServe)
- ;-
-
- ;+
- ; PP 1.0
- ; DESCRIPTION
- ; PP is a function for producing pretty-printed XLISP code. Version 1.0
- ; works with XLISP 1.4 and may work with other versions of XLISP or other
- ; lisp systems.
- ;
- ; UPDATE HISTORY
- ; Version 1.0 - Original version, 11 April 1985 by Gregory Frascadore.
- ;
- ;-
-
- ;+
- ; pp
- ; This function pretty-prints an s-expression.
- ;
- ; format
- ; (pp <expr> [<sink>] )
- ;
- ; <expr> the expression to print.
- ; <sink> optional. the sink to print to. defaults to
- ; *standard-output*
- ; <maxlen> the threshold that pp uses to determine when an expr
- ; should be broken into several lines. The smaller the
- ; value, the more lines are used. Defaults to 45 which
- ; seems reasonable and works well too.
- ;-
-
- (let ((pp-stack* nil)
- (pp-istack* nil)
- (pp-currentpos* nil)
- (pp-sink* nil)
- (pp-maxlen* nil))
-
- (defun pp (*expr &optional *sink *maxlen)
- (setq pp-stack* nil
- pp-istack* '(0)
- pp-currentpos* 0
- pp-sink* *sink
- pp-maxlen* *maxlen)
-
- (if (null pp-sink*) (setq pp-sink* *standard-output*))
- (if (null pp-maxlen*) (setq pp-maxlen* 45))
-
- (pp-expr *expr)
- (pp-newline)
- t)
-
-
- (defun pp-expr (*expr)
- (cond ((consp *expr)
- (pp-list *expr) )
-
- (t (pp-prin1 *expr)) ) )
-
-
- ;+
- ; pp-list
- ; Pretty-print a list expression.
- ; IF <the flatsize length of *expr is less than pp-maxlen*>
- ; THEN print the expression on one line,
- ; ELSE
- ; IF <the car of the expression is an atom>
- ; THEN print the expression in the following form:
- ; "(atom <item1>
- ; <item2>
- ; ...
- ; <itemn> )"
- ; ELSE
- ; IF <the car of the expression is a list>
- ; THEN print the expression in the following form:
- ; "(<list1>
- ; <item2>
- ; ...
- ; <itemn> )"
- ;
- ;-
-
- (defun pp-list (*expr)
- (cond ((< (flatsize *expr) pp-maxlen*)
- (pp-prin1 *expr) )
-
- ((atom (car *expr))
- (pp-start)
- (pp-prin1 (car *expr))
- (pp-princ " ")
- (pp-pushmargin)
- (pp-rest (cdr *expr))
- (pp-popmargin)
- (pp-finish) )
-
- (t (pp-start)
- (pp-pushmargin)
- (pp-rest *expr)
- (pp-popmargin)
- (pp-finish) ) ) )
-
- ;+
- ; pp-rest
- ; pp-expr each element of a list and do a pp-newline after every call to
- ; pp-expr except the last.
- ;-
-
- (defun pp-rest (*rest)
- (do* ((item* *rest (cdr item*)))
- ((null item*))
- (pp-expr (car item*))
- (if (not (null (cdr item*))) (pp-newline)) ) )
-
- ;+
- ; pp-newline
- ; Print out a newline character and indent to the current margin setting
- ; which is maintained at the top of the pp-istack. Note that is the
- ; current top of the pp-stack* is a ")" we push a " " so that we will know
- ; to print a space before closing any parenthesis which were started on a
- ; different line from the one they are being closed on.
- ;-
-
- (defun pp-newline ()
- (if (eql ")" (pp-top pp-stack*)) (pp-push " " pp-stack*))
-
- (terpri pp-sink*)
- (spaces (pp-top pp-istack*) pp-sink*)
- (setq pp-currentpos* (pp-top pp-istack*)) )
-
- ;+
- ; pp-finish
- ; Print out the closing ")". If the top of the pp-stack* has a " " on it,
- ; then print out the space, then the ")" , and then pop both off the stack.
- ;-
-
- (defun pp-finish ()
- (cond ((eql ")" (pp-top pp-stack*))
- (pp-princ ")") )
-
- (t
- (pp-princ " )")
- (pp-pop pp-stack*) ) )
-
- (pp-pop pp-stack*) )
-
-
- ;+
- ; pp-start
- ; Start printing a list. ie print the "(" and push a ")" on the pp-stack*
- ; so that pp-finish knows to print a ")" when closing an list.
- ;-
-
- (defun pp-start ()
- (pp-princ "(")
- (pp-push ")" pp-stack*) )
-
- ;+
- ; pp-princ
- ; Prints out an expr without any quotes and updates the pp-currentpos*
- ; pointer so that we know where on the line the cursor is at.
- ;-
-
- (defun pp-princ (*expr)
- (setq pp-currentpos* (+ pp-currentpos* (flatc *expr)))
- (princ *expr pp-sink*) )
-
- ;+
- ; pp-prin1
- ; Does the same thing as pp-prin1, except that the expr is printed with
- ; quotes if needed. Hence pp-prin1 uses flatsize to calc expr length instead
- ; of flatc.
- ;-
-
- (defun pp-prin1 (*expr)
- (setq pp-currentpos* (+ pp-currentpos* (flatsize *expr)))
- (prin1 *expr pp-sink*) )
-
- (defmacro pp-push (*item *stack)
- `(setq ,*stack (cons ,*item ,*stack)) )
-
-
- (defmacro pp-pop (*stack)
- `(let ((top* (car ,*stack)))
-
- (setq ,*stack (cdr ,*stack))
- top*) )
-
-
- (defun pp-top (*stack) (car *stack))
-
-
- (defun pp-pushmargin ()
- (pp-push pp-currentpos* pp-istack*) )
-
-
- (defun pp-popmargin ()
- (pp-pop pp-istack*) )
-
- (defun spaces (n f)
- (dotimes (x n) (write-char 32 f)))
-
- )
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'prolog.lsp'
- then
- echo shar: will not over-write existing file "'prolog.lsp'"
- else
- cat << \SHAR_EOF > 'prolog.lsp'
-
- ;; The following is a tiny Prolog interpreter in MacLisp
- ;; written by Ken Kahn and modified for XLISP by David Betz.
- ;; It was inspired by other tiny Lisp-based Prologs of
- ;; Par Emanuelson and Martin Nilsson.
- ;; There are no side-effects anywhere in the implementation.
- ;; Though it is VERY slow of course.
-
- (defun prolog (database &aux goal)
- (do () ((not (progn (princ "Query?") (setq goal (read)))))
- (prove (list (rename-variables goal '(0)))
- '((bottom-of-environment))
- database
- 1)))
-
- ;; prove - proves the conjunction of the list-of-goals
- ;; in the current environment
-
- (defun prove (list-of-goals environment database level)
- (cond ((null list-of-goals) ;; succeeded since there are no goals
- (print-bindings environment environment)
- (not (y-or-n-p "More?")))
- (t (try-each database database
- (cdr list-of-goals) (car list-of-goals)
- environment level))))
-
- (defun try-each (database-left database goals-left goal environment level
- &aux assertion new-enviroment)
- (cond ((null database-left) nil) ;; fail since nothing left in database
- (t (setq assertion
- (rename-variables (car database-left)
- (list level)))
- (setq new-environment
- (unify goal (car assertion) environment))
- (cond ((null new-environment) ;; failed to unify
- (try-each (cdr database-left) database
- goals-left goal
- environment level))
- ((prove (append (cdr assertion) goals-left)
- new-environment
- database
- (+ 1 level)))
- (t (try-each (cdr database-left) database
- goals-left goal
- environment level))))))
-
- (defun unify (x y environment &aux new-environment)
- (setq x (value x environment))
- (setq y (value y environment))
- (cond ((variable-p x) (cons (list x y) environment))
- ((variable-p y) (cons (list y x) environment))
- ((or (atom x) (atom y))
- (cond ((equal x y) environment)
- (t nil)))
- (t (setq new-environment (unify (car x) (car y) environment))
- (cond (new-environment (unify (cdr x) (cdr y) new-environment))
- (t nil)))))
-
- (defun value (x environment &aux binding)
- (cond ((variable-p x)
- (setq binding (assoc x environment :test #'equal))
- (cond ((null binding) x)
- (t (value (cadr binding) environment))))
- (t x)))
-
- (defun variable-p (x)
- (and x (listp x) (eq (car x) '?)))
-
- (defun rename-variables (term list-of-level)
- (cond ((variable-p term) (append term list-of-level))
- ((atom term) term)
- (t (cons (rename-variables (car term) list-of-level)
- (rename-variables (cdr term) list-of-level)))))
-
- (defun print-bindings (environment-left environment)
- (cond ((cdr environment-left)
- (cond ((= 0 (nth 2 (caar environment-left)))
- (prin1 (cadr (caar environment-left)))
- (princ " = ")
- (print (value (caar environment-left) environment))))
- (print-bindings (cdr environment-left) environment))))
-
- ;; a sample database:
- (setq db '(((father madelyn ernest))
- ((mother madelyn virginia))
- ((father david arnold))
- ((mother david pauline))
- ((father rachel david))
- ((mother rachel madelyn))
- ((grandparent (? grandparent) (? grandchild))
- (parent (? grandparent) (? parent))
- (parent (? parent) (? grandchild)))
- ((parent (? parent) (? child))
- (mother (? parent) (? child)))
- ((parent (? parent) (? child))
- (father (? parent) (? child)))))
-
- ;; the following are utilities
- (defun y-or-n-p (prompt)
- (princ prompt)
- (eq (read) 'y))
-
- ;; start things going
- (prolog db)
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'pt.lsp'
- then
- echo shar: will not over-write existing file "'pt.lsp'"
- else
- cat << \SHAR_EOF > 'pt.lsp'
- ; This is a sample XLISP program
- ; It implements a simple form of programmable turtle for VT100 compatible
- ; terminals.
-
- ; To run it:
-
- ; A>xlisp pt
-
- ; This should cause the screen to be cleared and two turtles to appear.
- ; They should each execute their simple programs and then the prompt
- ; should return. Look at the code to see how all of this works.
-
- ; Get some more memory
- (expand 1)
-
- ; Clear the screen
- (defun clear ()
- (princ "\e[H\e[J"))
-
- ; Move the cursor
- (defun setpos (x y)
- (princ "\e[") (princ y) (princ ";") (princ x) (princ "H"))
-
- ; Kill the remainder of the line
- (defun kill ()
- (princ "\e[K"))
-
- ; Move the cursor to the currently set bottom position and clear the line
- ; under it
- (defun bottom ()
- (setpos bx (+ by 1))
- (kill)
- (setpos bx by)
- (kill))
-
- ; Clear the screen and go to the bottom
- (defun cb ()
- (clear)
- (bottom))
-
-
- ; ::::::::::::
- ; :: Turtle ::
- ; ::::::::::::
-
- ; Define "Turtle" class
- (setq Turtle (Class :new '(xpos ypos char)))
-
- ; Answer ":isnew" by initing a position and char and displaying.
- (Turtle :answer :isnew '() '(
- (setq xpos (setq newx (+ newx 1)))
- (setq ypos 12)
- (setq char "*")
- (self :display)
- self))
-
- ; Message ":display" prints its char at its current position
- (Turtle :answer :display '() '(
- (setpos xpos ypos)
- (princ char)
- (bottom)
- self))
-
- ; Message ":char" sets char to its arg and displays it
- (Turtle :answer :char '(c) '(
- (setq char c)
- (self :display)))
-
- ; Message ":goto" goes to a new place after clearing old one
- (Turtle :answer :goto '(x y) '(
- (setpos xpos ypos) (princ " ")
- (setq xpos x)
- (setq ypos y)
- (self :display)))
-
- ; Message ":up" moves up if not at top
- (Turtle :answer :up '() '(
- (if (> ypos 0)
- (self :goto xpos (- ypos 1))
- (bottom))))
-
- ; Message ":down" moves down if not at bottom
- (Turtle :answer :down '() '(
- (if (< ypos by)
- (self :goto xpos (+ ypos 1))
- (bottom))))
-
- ; Message ":right" moves right if not at right
- (Turtle :answer :right '() '(
- (if (< xpos 80)
- (self :goto (+ xpos 1) ypos)
- (bottom))))
-
- ; Message ":left" moves left if not at left
- (Turtle :answer :left '() '(
- (if (> xpos 0)
- (self :goto (- xpos 1) ypos)
- (bottom))))
-
-
- ; :::::::::::::
- ; :: PTurtle ::
- ; :::::::::::::
-
- ; Define "DPurtle" programable turtle class
- (setq PTurtle (Class :new '(prog pc) '() Turtle))
-
- ; Message ":program" stores a program
- (PTurtle :answer :program '(p) '(
- (setq prog p)
- (setq pc prog)
- self))
-
- ; Message ":step" executes a single program step
- (PTurtle :answer :step '() '(
- (if (null pc)
- (setq pc prog))
- (if pc
- (progn (self (car pc))
- (setq pc (cdr pc))))
- self))
-
- ; Message ":step#" steps each turtle program n times
- (PTurtle :answer :step# '(n) '(
- (dotimes (x n) (self :step))
- self))
-
-
- ; ::::::::::::::
- ; :: PTurtles ::
- ; ::::::::::::::
-
- ; Define "PTurtles" class
- (setq PTurtles (Class :new '(turtles)))
-
- ; Message ":make" makes a programable turtle and adds it to the collection
- (PTurtles :answer :make '(x y &aux newturtle) '(
- (setq newturtle (PTurtle :new))
- (newturtle :goto x y)
- (setq turtles (cons newturtle turtles))
- newturtle))
-
- ; Message ":step" steps each turtle program once
- (PTurtles :answer :step '() '(
- (mapcar '(lambda (turtle) (turtle :step)) turtles)
- self))
-
- ; Message ":step#" steps each turtle program n times
- (PTurtles :answer :step# '(n) '(
- (dotimes (x n) (self :step))
- self))
-
-
- ; Initialize things and start up
- (setq bx 0)
- (setq by 20)
- (setq newx 0)
-
- ; Create some programmable turtles
- (cb)
- (setq turtles (PTurtles :new))
- (setq t1 (turtles :make 40 10))
- (setq t2 (turtles :make 41 10))
- (t1 :program '(:left :right :up :down))
- (t2 :program '(:right :left :down :up))
-
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'queens.lsp'
- then
- echo shar: will not over-write existing file "'queens.lsp'"
- else
- cat << \SHAR_EOF > 'queens.lsp'
- ;
- ; Place n queens on a board
- ; See Winston and Horn Ch. 11
- ;
- ; Usage:
- ; (queens <n>)
- ; where <n> is an integer -- the size of the board - try (queens 4)
-
- (defun cadar (x)
- (car (cdr (car x))))
-
- ; Do two queens threaten each other ?
- (defun threat (i j a b)
- (or (equal i a) ;Same row
- (equal j b) ;Same column
- (equal (- i j) (- a b)) ;One diag.
- (equal (+ i j) (+ a b)))) ;the other diagonal
-
- ; Is poistion (n,m) on the board safe for a queen ?
- (defun conflict (n m board)
- (cond ((null board) nil)
- ((threat n m (caar board) (cadar board)) t)
- (t (conflict n m (cdr board)))))
-
-
- ; Place queens on a board of size SIZE
- (defun queens (size)
- (prog (n m board)
- (setq board nil)
- (setq n 1) ;Try the first row
- loop-n
- (setq m 1) ;Column 1
- loop-m
- (cond ((conflict n m board) (go un-do-m))) ;Check for conflict
- (setq board (cons (list n m) board)) ; Add queen to board
- (cond ((> (setq n (1+ n)) size) ; Placed N queens ?
- (print (reverse board)))) ; Print config
- (go loop-n) ; Next row which column?
- un-do-n
- (cond ((null board) (return 'Done)) ; Tried all possibilities
- (t (setq m (cadar board)) ; No, Undo last queen placed
- (setq n (caar board))
- (setq board (cdr board))))
-
- un-do-m
- (cond ((> (setq m (1+ m)) size) ; Go try next column
- (go un-do-n))
- (t (go loop-m)))))
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'queens2.lsp'
- then
- echo shar: will not over-write existing file "'queens2.lsp'"
- else
- cat << \SHAR_EOF > 'queens2.lsp'
- ;
- ; Place n queens on a board (graphical version)
- ; See Winston and Horn Ch. 11
- ;
- ; Usage:
- ; (queens <n>)
- ; where <n> is an integer -- the size of the board - try (queens 4)
-
- (defun cadar (x)
- (car (cdr (car x))))
-
- ; Do two queens threaten each other ?
- (defun threat (i j a b)
- (or (equal i a) ;Same row
- (equal j b) ;Same column
- (equal (- i j) (- a b)) ;One diag.
- (equal (+ i j) (+ a b)))) ;the other diagonal
-
- ; Is poistion (n,m) on the board safe for a queen ?
- (defun conflict (n m board)
- (cond ((null board) nil)
- ((threat n m (caar board) (cadar board)) t)
- (t (conflict n m (cdr board)))))
-
-
- ; Place queens on a board of size SIZE
- (defun queens (size)
- (prog (n m board soln)
- (setq soln 0) ;Solution #
- (setq board nil)
- (setq n 1) ;Try the first row
- loop-n
- (setq m 1) ;Column 1
- loop-m
- (cond ((conflict n m board) (go un-do-m))) ;Check for conflict
- (setq board (cons (list n m) board)) ; Add queen to board
- (cond ((> (setq n (1+ n)) size) ; Placed N queens ?
- (print-board (reverse board) (setq soln (1+ soln))))) ; Print it
- (go loop-n) ; Next row which column?
- un-do-n
- (cond ((null board) (return 'Done)) ; Tried all possibilities
- (t (setq m (cadar board)) ; No, Undo last queen placed
- (setq n (caar board))
- (setq board (cdr board))))
-
- un-do-m
- (cond ((> (setq m (1+ m)) size) ; Go try next column
- (go un-do-n))
- (t (go loop-m)))))
-
-
- ;Print a board
- (defun print-board (board soln &aux size)
- (setq size (length board)) ;we can find our own size
- (terpri)
- (princ "\t\tSolution: ")
- (print soln)
- (terpri)
- (princ "\t")
- (print-header size 1)
- (terpri)
- (print-board-aux board size 1)
- (terpri))
-
- ; Put Column #'s on top
- (defun print-header (size n)
- (cond ((> n size) terpri)
- (t (princ n)
- (princ " ")
- (print-header size (1+ n)))))
-
- (defun print-board-aux (board size row)
- (terpri)
- (cond ((null board))
- (t (princ row) ;print the row #
- (princ "\t")
- (print-board-row (cadar board) size 1) ;Print the row
- (print-board-aux (cdr board) size (1+ row))))) ;Next row
-
- (defun print-board-row (column size n)
- (cond ((> n size))
- (t (cond ((equal column n) (princ "Q"))
- (t (princ ".")))
- (princ " ")
- (print-board-row column size (1+ n)))))
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'simplepp.lsp'
- then
- echo shar: will not over-write existing file "'simplepp.lsp'"
- else
- cat << \SHAR_EOF > 'simplepp.lsp'
- ;
- ; a pretty-printer, with hooks for the editor
- ;
-
- ; First, the terminal width and things to manipulate it
- (setq pp$terminal-width 79)
-
- (defmacro get-terminal-width nil
- pp$terminal_width)
-
- (defmacro set-terminal-width (new-width)
- (let ((old-width pp$terminal-width))
- (setq pp$terminal-width new-width)
- old-width))
- ;
- ; Now, a basic, simple pretty-printer
- ; pp$pp prints expression, indented to indent-level, assuming that things
- ; have already been indented to indent-so-far. It *NEVER* leaves the cursor
- ; on a new line after printing expression. This is to make the recursion
- ; simpler. This may change in the future, in which case pp$pp could vanish.
- ;
- (defun pp$pp (expression indent-level indent-so-far)
- ; Step one, make sure we've indented to indent-level
- (dotimes (x (- indent-level indent-so-far)) (princ " "))
- ; Step two, if it's an atom or it fits just print it
- (cond ((or (not (consp expression))
- (> (- pp$terminal-width indent-level) (flatsize expression)))
- (prin1 expression))
- ; else, print open paren, the car, then each sub expression, then close paren
- (t (princ "(")
- (pp$pp (car expression) (1+ indent-level) (1+ indent-level))
- (if (cadr expression)
- (progn
- (if (or (consp (car expression))
- (> (/ (flatsize (car expression)) 3)
- pp$terminal-width))
- (progn (terpri)
- (pp$pp (cadr expression)
- (1+ indent-level)
- 0))
- (pp$pp (cadr expression)
- (+ 2 indent-level (flatsize (car expression)))
- (+ 1 indent-level (flatsize (car expression)))))
- (dolist (current-expression (cddr expression))
- (terpri)
- (pp$pp current-expression
- (+ 2 indent-level
- (flatsize (car expression)))
- 0))))
- (princ ")")))
- nil)
- ;
- ; Now, the thing that outside users should call
- ; We have to have an interface layer to get the final terpri after pp$pp.
- ; This also allows hiding the second and third args to pp$pp. Said args
- ; being required makes the pp recursion loop run faster (don't have to map
- ; nil's to 0).
- ; The where arg to pp is ingnored, as the obvious hack to pp$pp [adding
- ; an extra arg to every call to a print routine or pp$pp] doesn't work,
- ; printing nothing when where is nil.
- ;
- (defun pp (expression &optional where)
- "Print EXPRESSION on STREAM, prettily"
- (pp$pp expression 0 0)
- (terpri))
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'trace.lsp'
- then
- echo shar: will not over-write existing file "'trace.lsp'"
- else
- cat << \SHAR_EOF > 'trace.lsp'
- (setq *tracelist* nil)
-
- (defun evalhookfcn (expr &aux val)
- (if (and (consp expr) (member (car expr) *tracelist*))
- (progn (princ ">>> ") (print expr)
- (setq val (evalhook expr evalhookfcn nil))
- (princ "<<< ") (print val))
- (evalhook expr evalhookfcn nil)))
-
- (defun trace (fun)
- (if (not (member fun *tracelist*))
- (progn (setq *tracelist* (cons fun *tracelist*))
- (setq *evalhook* evalhookfcn)))
- *tracelist*)
-
- (defun untrace (fun)
- (if (null (setq *tracelist* (delete fun *tracelist*)))
- (setq *evalhook* nil))
- *tracelist*)
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-